package com.behelpful.demo.quartz.utils;

import cn.hutool.core.util.StrUtil;
import com.behelpful.common.core.exceptions.ParamException;
import com.behelpful.common.core.result.ErrorResult;
import com.behelpful.common.core.utils.ExceptionUtil;
import com.behelpful.demo.quartz.entity.SystemJob;
import com.behelpful.demo.quartz.job.IQuartzJob;
import org.quartz.*;

/**
 * Quartz 工具类封装
 *
 * @author Alay
 * @date 2021-10-31 19:05
 * @since
 */
public class IQuartzUtil {

    public static String SCHEDULE_JOB_KEY = "scheduleJob";

    /**
     * 添加新的定时任务
     *
     * @param systemJob
     * @param scheduler
     */
    public static void addNewJob(SystemJob systemJob, Scheduler scheduler) {
        // 构建一个 JobDetail
        JobDetail jobDetail = IQuartzUtil.buildJobDetail(systemJob);
        // 构建 Trigger
        Trigger trigger = IQuartzUtil.buildCronTrigger(systemJob);
        try {
            //交由Scheduler安排触发
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 暂停任务
     *
     * @param systemJob
     * @param scheduler
     */
    public static void pauseJob(SystemJob systemJob, Scheduler scheduler) {
        try {
            scheduler.pauseJob(getJobKey(systemJob));
        } catch (SchedulerException exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 运行单个定时任务
     *
     * @param systemJob
     * @param scheduler
     */
    public static boolean runJob(SystemJob systemJob, Scheduler scheduler) {
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put(SCHEDULE_JOB_KEY, scheduler);
        try {
            scheduler.triggerJob(getJobKey(systemJob), jobDataMap);
        } catch (SchedulerException exception) {
            exception.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 移除定时任务
     *
     * @param systemJob
     * @param scheduler
     */
    public static boolean removeJob(SystemJob systemJob, Scheduler scheduler) {
        boolean isOk = false;
        TriggerKey triggerKey = getTriggerKey(systemJob);
        try {
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // scheduler
            isOk = scheduler.unscheduleJob(triggerKey);
            if (isOk) {
                JobKey jobKey = IQuartzUtil.getJobKey(systemJob);
                // 删除任务
                isOk = scheduler.deleteJob(jobKey);
            }
        } catch (SchedulerException exception) {
            exception.printStackTrace();
        }
        return isOk;
    }

    /**
     * 构建一个新的 JobDetail 实例
     *
     * @param systemJob
     * @return
     */
    public static JobDetail buildJobDetail(SystemJob systemJob) {
        // 新建一个工作任务 指定任务类型为串接进行的
        JobDetail jobDetail = JobBuilder.newJob(IQuartzJob.class)
                .withIdentity(getJobKey(systemJob))
                .withDescription(systemJob.getDescription())
                .build();
        return jobDetail;
    }


    /**
     * 构建 CronTrigger
     *
     * @param systemJob
     * @return
     */
    public static Trigger buildCronTrigger(SystemJob systemJob) {
        // 触发时间点(Cron表达式构建)
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(systemJob.getCronExpression());
        // 创建触发器并将cron表达式对象给塞入
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(getTriggerKey(systemJob))
                .withSchedule(cronScheduleBuilder)
                .build();
        return cronTrigger;
    }


    /**
     * 获取任务唯一 Key
     *
     * @param systemJob
     * @return
     */
    public static JobKey getJobKey(SystemJob systemJob) {
        String jobName = systemJob.getJobName();
        String jobGroup = systemJob.getJobGroup();
        if (StrUtil.isBlank(jobName) || StrUtil.isBlank(jobGroup)) {
            throw ExceptionUtil.create(ParamException.class, ErrorResult.PARAMETER_ERROR);
        }
        JobKey key = JobKey.jobKey(jobName, jobGroup);
        return key;
    }

    /**
     * 获取任务唯一 Key
     *
     * @return
     */
    public static TriggerKey getTriggerKey(SystemJob systemJob) {
        String jobName = systemJob.getJobName();
        String jobGroup = systemJob.getJobGroup();
        if (StrUtil.isBlank(jobName) || StrUtil.isBlank(jobGroup)) {
            throw ExceptionUtil.create(ParamException.class, ErrorResult.PARAMETER_ERROR);
        }
        return TriggerKey.triggerKey(jobName, jobGroup);
    }

}
